package com.kfm.pm;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class TransferDemo {

    public static void main(String[] args) {
        transfer3();
    }

    /**
     * 不在事务中进行转账 发生异常 会造成财产损失
     *
     * @throws ClassNotFoundException
     * @throws SQLException
     */
    private static void transfer() throws ClassNotFoundException, SQLException {
        // 转账
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/manager", "root", "");
        String sql = "update account set balance = balance - ? where id = ?";
        PreparedStatement prepared = connection.prepareStatement(sql);
        // 小张转出钱
        prepared.setObject(1, 8000);
        prepared.setObject(2, 1);
        int i = prepared.executeUpdate();
        if (i > 0) {
            System.out.println("转出成功");
        } else {
            System.out.println("转出失败");
        }
        int a = 1 / 0;
        // 小张嫂转进来钱
        prepared.setObject(1, -8000);
        prepared.setObject(2, 2);
        int i1 = prepared.executeUpdate();
        if (i1 > 0) {
            System.out.println("转入成功");
        } else {
            System.out.println("转入失败");
        }

    }


    /**
     * 在事务中进行转账  让转出和转入 应该在同一个事务 如果发生异常 回滚 如果一切正常 提交事务
     * 将当前连接的自动提交模式修改是 false
     * 执行事务  executeUpdate()
     * 如果没有任何异常：提交事务 commit() try
     * 一旦发生异常：回滚事务 rollback(); catch
     * 同一个事务中 成批的sql 要么全部执行成功 要么一个发生问题 撤销执行的内容
     *
     * @throws ClassNotFoundException
     * @throws SQLException
     */
    private static void transfer2() {
        // 转账
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
        Connection connection = null;
        try {
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/manager", "root", "");
            // 将当前连接的自动提交模式修改为手动
            connection.setAutoCommit(false);
            String sql = "update account set balance = balance - ? where id = ?";
            PreparedStatement prepared = connection.prepareStatement(sql);
            // 小张转出钱
            prepared.setObject(1, 8000);
            prepared.setObject(2, 1);
            // 执行事务
            int i = prepared.executeUpdate();
            if (i > 0) {
                System.out.println("转出成功");
            } else {
                System.out.println("转出失败");
            }
//            int a = 1 / 0;
            // 小张嫂转进来钱
            prepared.setObject(1, -8000);
            prepared.setObject(2, 2);
            // 执行事务
            int i1 = prepared.executeUpdate();
            if (i1 > 0) {
                System.out.println("转入成功");
            } else {
                System.out.println("转入失败");
            }
            // 提交事务
            connection.commit();
            System.out.println("提交事务成功");
        } catch (SQLException e) {
            if (connection != null) {
                try {
                    // 回滚事务
                    connection.rollback();
                } catch (SQLException ex) {
                    throw new RuntimeException(ex);
                }
            }
        } catch (ArithmeticException e) {
            if (connection != null) {
                try {
                    System.out.println("事务回滚");
                    // 回滚事务
                    connection.rollback();
                } catch (SQLException ex) {
                    throw new RuntimeException(ex);
                }
            }
        }


    }


    private static void transfer3() {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }

        Connection conn = null;
        try {
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/manager;", "root", "");
            // 修改提交模式 开启事务
            conn.setAutoCommit(false);
            String sql = "update account set balance = balance - ? where id = ?";
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setObject(1, 8000);
            ps.setObject(2, 1);
            // 执行sql  执行事务
            int i = ps.executeUpdate();
            if (i > 0) {
                System.out.println("转出成功");
            } else {
                System.out.println("转出失败");
            }
            int a = 1 / 0;
            ps.setObject(1, -8000);
            ps.setObject(2, 2);
            // 执行事务
            int i1 = ps.executeUpdate();
            if (i1 > 0) {
                System.out.println("转入成功");
            } else {
                System.out.println("转入失败");
            }
            // 没有发生任何异常 提交事务
            conn.commit();

        } catch (SQLException | ArithmeticException e) {
            e.printStackTrace();
            // 发生了异常 回滚事务 撤销在当前事务中进行的一切操作
//            try {
//                conn.rollback();
//            } catch (SQLException ex) {
//                throw new RuntimeException(ex);
//            }
            if (conn != null) {
                try {
                    conn.rollback();
                    System.out.println("回滚事务");
                } catch (SQLException ex) {
                    e.printStackTrace();
                }
            }

        }

    }
}
